<?php
/**
 * 订单服务层
 * 2019.3.13
 * 吴
 */
namespace app\api\service;

use think\Db;
use think\Cache;

class OrderService{



	/**
     * 创建订单
     *
     * @param goods_id = 商品ID 
     * @param number = 商品数量 
     * @param addr_info = 收货地址 
     * @param payment_type = 支付类型：1=余额支付，2=微信支付，3=支付宝支付
     */
	public function createOrder($goods_id,$number = 1,$addr_info,$payment_type=1,$user_info){
		$out_trade_no = $this->createOutTradeNo();
		$order_no = $this->createOrderNo();
		$goods_info = Db::name('goods')->where('goods_id',$goods_id)->find();
		$addr = Db::name('region')->field('id,name')->select();
		foreach ($addr as $k => $v) {
			if($v['id'] == $addr_info['province']){
				$province = $v['name'];
			}
			if($v['id'] == $addr_info['city']){
				$city = $v['name'];
			}
			if($v['id'] == $addr_info['district']){
				$district = $v['name'];
			}
		}
		$address = $province.'-'.$city.'-'.$district.'-'.$addr_info['address'];
        // $req = request();
        // $domain = $req->domain();
		$data = [
           'order_no'       => $order_no,
           'out_trade_no'   => $out_trade_no,
           'user_id'        => $user_info['user_id'],
           'user_name'      => $user_info['user_name'],
           'goods_id'       => $goods_id,
           'goods_name'     => $goods_info['goods_title'],
           // 'goods_thumb'    => $domain.$goods_info['goods_thumb'],
           'goods_thumb'    => $goods_info['goods_thumb'],
           'goods_price'    => $goods_info['goods_price'],
           'number'         => $number,
           'order_money'    => $number*$goods_info['goods_price'],
           'payment_type'   => 1,
           'parment_status' => 0,
           'order_status'   => 0,
           'addr_id'        => $addr_info['id'],
           'receiver_name'  => $addr_info['consigner'],
           'receiver_mobile'=> $addr_info['mobile'],
           'receiver_zip'   => $addr_info['zip_code'],
           'address'        => $address,
           'pay_money'      => $number*$goods_info['goods_price'],
           'create_time'    => date('Y-m-d H:i:s',time()),
		];
        Db::startTrans(); //启动事务
		try {
	    $order_id = Db::name('order')->insertGetId($data);
			Db::commit(); //提交事务
		} catch (\PDOException $e) {
			Db::rollback(); //回滚事务
		}
		$info = [
		   'order_id'     => $order_id,
           'order_money'  => $number*$goods_info['goods_price'],
           'out_trade_no' => $out_trade_no
		];
        return $info;

	}



	/**
     * 创建支付订单编号
     */
    public function createOutTradeNo()
    {
        $cache = Cache::get("six_shop_bfd".date("Y/m/d"));
        if (empty($cache)) {
            Cache::set("six_shop_bfd".date("Y/m/d"), 1000);
            $cache = Cache::get("six_shop_bfd".date("Y/m/d"));
        } else {
            $cache = $cache + 1;
            Cache::set("six_shop_bfd".date("Y/m/d"), $cache);
        }
        $no = time().rand(1000, 9999).$cache;
        return $no;
    }


    /**
     * 得到订单的订单号
     */
    public function createOrderNo(){
        $time_str   = date('YmdHis');
        $order_no_max = Db::name('order')->order('order_id', 'desc')->value('order_no');
        $num = 0;
        if(empty($order_no_max)){
            $num = 1;
        }else{
            if(substr($time_str, 0, 8) == substr($order_no_max, 0, 8)) {
                $max_no = substr($order_no_max, 14, 9);
                $num    = str_replace("0", "", $max_no) + 1;
            }else{
                $num = 1;
            }
        }
        $order_no = $time_str . sprintf("%09d", $num);
        return $order_no;
    }



    /**
     * 订单支付
     *
     * @param out_trade_no = 外部交易号 必填
     * @param payment_type = 支付类型 必填
     * @param pay_code = 支付密码 必填
     */
    public function orderPayment($out_trade_no,$payment_type = 1,$pay_code,$user_info){
        $order_info = Db::name('order')->where('out_trade_no',$out_trade_no)->find();
        if(empty($order_info)){
        	return ['code' => -1,'msg'=>'没有获取到订单信息'];
        }
        $goods_info = Db::name('goods')->where('goods_id',$order_info['goods_id'])->find();
        if($goods_info['goods_stock'] < $order_info['number']){
        	return ['code' => -1,'msg'=>'库存不足'];
        }
        if($order_info['parment_status'] == 1){
        	return ['code' => -1,'msg'=>'订单已经支付或者订单价格为0.00，无需再次支付!'];
        }
        if($user_info['balance'] < $order_info['order_money']){
        	return ['code' => -1,'msg'=>'用户余额不足'];
        }
        //去减少用户余额
        $data = [
           'balance'   => $user_info['balance'] - $order_info['order_money'],
        ];
        //扣款
      	Db::startTrans(); //启动事务
    	try {
    	    Db::name('shop_user')->where('user_id',$user_info['user_id'])->update($data);
    	    Db::commit(); //提交事务
    	} catch (\PDOException $e) {
    		Db::rollback(); //回滚事务
    	}
		    //这里预留添加明细
        $balance_info = [
            'money'       => $order_info['order_money'],
            'scene'       => 4, 
            'sign'        => 2,
            'create_time' => date('Y-m-d H:i:s',time()),
            'user_id'     => $user_info['user_id'],
            'remarks'     => '购买商品扣款',
            'data_id'     => $order_info['order_id'],
        ];
        $balance = $this->addBalanceInfo($balance_info);
        if(!$balance){
          return ['code' => -1,'msg'=>'添加明细失败'];
        }
        //扣库存
        $res = $this->reduceStock($order_info['goods_id'],$order_info['number']);
        if(!$res){
        	return ['code' => -1,'msg'=>'库存不足'];
        }
        //修改订单状态
        $order = [
           'payment_type'    => $payment_type,
           'parment_status'  => 1,
           'order_status'    => 1,
           'pay_time'        => date('Y-m-d H:i:s',time()),
        ];
        Db::startTrans(); //启动事务
    	try {
    	    $row = Db::name('order')->where('out_trade_no',$out_trade_no)->update($order);
    	    Db::commit(); //提交事务
    	} catch (\PDOException $e) {
    		Db::rollback(); //回滚事务
    	}
        if($row){
           return ['code' => 10000,'msg'=>'支付成功'];
        }else{
           return ['code' => -1,'msg'=>'支付失败'];
        }
        

    }



    /**
     * 扣库存
     *
     * @param  goods_id 商品ID
     * @param  goods_id 库存数量
     */
    public function reduceStock($goods_id,$stock){
        $res = Db::name('goods')
             ->where('goods_id',$goods_id)
             ->setDec('goods_stock', $stock);
        if($res){
        	return true;
        }else{
        	return false;
        }
    }


    /**
     * 添加余额明细
     *
     * @param  data 明细
     */
    public function addBalanceInfo($data){
        Db::startTrans(); //启动事务
        try {
            $res = Db::name('balance_record')->insert($data);
            Db::commit(); //提交事务
        } catch (\PDOException $e) {
            Db::rollback(); //回滚事务
        }
        if($res){
          return true;
        }else{
          return false;
        }
    }



    /**
     * 奖金推送
     *
     * @param  user_info 用户ID
     * @param  order_info 订单信息
     */
    public function bonusPush($user_info,$order_info){
        if(empty($user_info['first_leader'])){
            return true;
        }
        $first = Db::name('shop_user')->where('user_id',$user_info['first_leader'])->find();
        $money = $this->bonusNumber($first,1);
        $data = [
            'balance'      => $first['balance'] + $money*$order_info['number'],
            'volume'       => $first['volume'] + $order_info['number'], 
            'recom_money'  => $first['recom_money'] + $money*$order_info['number'],
            'first_volume' => $first['first_volume'] + $order_info['number'],
        ];
        Db::startTrans(); //启动事务
        try {
            $res = Db::name('shop_user')->where('user_id',$user_info['first_leader'])->update($data);
            Db::commit(); //提交事务
        } catch (\PDOException $e) {
            Db::rollback(); //回滚事务
        }
        if(!$res){
            return false;
        }
        //判断会员是否晋升
        $this->userLevel($user_info['first_leader']);
        //加入明细
        $balance_info = [
            'money'       => $money*$order_info['number'],
            'scene'       => 5,
            'sign'        => 1,
            'create_time' => date('Y-m-d H:i:s',time()),
            'user_id'     => $user_info['first_leader'],
            'remarks'     => '奖励',
            'data_id'     => $order_info['order_id'],
        ];
        $balance = $this->addBalanceInfo($balance_info);
        if(!$balance){
          return false;
        }
        //二级，可优化一个循环
        if(empty($user_info['second_leader']) && empty($first['first_leader']) || $user_info['second_leader'] != $first['first_leader']){
          return true;
        }
        $second = Db::name('shop_user')->where('user_id',$user_info['second_leader'])->find();
        $second_money = $this->bonusNumber($second,2);
        $second_data = [
           'balance'       => $second['balance'] + $second_money*$order_info['number'],
           'volume'        => $second['volume'] + $order_info['number'], 
           'recom_money'   => $second['recom_money'] + $second_money*$order_info['number'],
           'second_volume' => $second['second_volume'] + $order_info['number'],
        ];
        Db::startTrans(); //启动事务
        try {
            $res = Db::name('shop_user')->where('user_id',$user_info['second_leader'])->update($second_data);
            Db::commit(); //提交事务
        } catch (\PDOException $e) {
            Db::rollback(); //回滚事务
        }
        if(!$res){
          return false;
        }
        //判断会员是否晋升
        $this->userLevel($user_info['second_leader']);
        //加入明细
        $second_info = [
            'money'       => $second_money*$order_info['number'],
            'scene'       => 5,
            'sign'        => 1,
            'create_time' => date('Y-m-d H:i:s',time()),
            'user_id'     => $user_info['second_leader'],
            'remarks'     => '奖励',
            'data_id'     => $order_info['order_id'],
        ];
        $second_balance = $this->addBalanceInfo($second_info);
        if($balance){
          return true;
        }else{
          return false;
        }
    }



    /**
     * 奖励金额
     *
     * @param  data 用户信息
     * @param  type 1，2
     */
    public function bonusNumber($data,$type){
        if($type == 2){
          $money = 300;
          return $money;
        }
        switch ($data['level']){
            case '0':
                $money = 600;
                break;
            case '1':
                $money = 750;
                break;
            case '2':
                $money = 890;
                break;
            case '3':
                $money = 1200;
                break;
            case '4':
                $money = 1350;
                break;
            case '5':
                $money = 1500;
                break;
        }
        return $money;
    }



    /**
     * 会员等级晋升
     */
    public function userLevel($user_id){
        $info = Db::name('shop_user')->where('user_id',$user_id)->find();
        if($info['oneself_volume'] == 0){
          return true;
        }
        //升级黄金
        if($info['first_volume'] > 4 && $info['level'] < 1){
          Db::name('shop_user')->where('user_id',$user_id)->update(['level' => 1]);
          $data = [
             'user_id'    => $user_id,
             'level'      => 1,
             'createtime' => date('Y-m-d H:i:s',time()), 
          ];
          $res = Db::name('user_level_info')->insert($data);
          if($res){
            return true;
          }else{
            return false;
          }
        }
        //升级铂金
        $data = Db::name('shop_user')->where('first_leader = '.$user_id.' AND level < 0')->count();
        if($data > 9 && $info['level'] < 2){
            Db::name('shop_user')->where('user_id',$user_id)->update(['level' => 2]);
            $data = [
              'user_id'    => $user_id,
              'level'      => 2,
              'createtime' => date('Y-m-d H:i:s',time()), 
            ];
            $res = Db::name('user_level_info')->insert($data);
            if($res){
              return true;
            }else{
              return false;
            }
        }else{
          return true;
        }
    }



    /**
     *查询物流
     *
     * $no = 物流单号
     */
    public function express($no){
        $host = "https://kuaidi101.market.alicloudapi.com";
        $path = "/getExpress";
        $method = "GET";
        $appcode = "eaf8824a23384736b8cde69e89073829";
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        $querys = "NO=".$no."&TYPE=AUTO";
        $bodys = "";
        $url = $host . $path . "?" . $querys;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        if (1 == strpos("$".$host, "https://"))
        {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        return curl_exec($curl);
    }



    /**
     * 完成订单
     *
     * @param order_info 订单信息
     * @param user_info  用户信息
     * @param type !== '' 则当做执行定时任务
     */
    public function completeOrder($order_info,$user_info,$type = ''){
        //修改订单状态
        $res = Db::name('order')->where('order_id',$order_info['order_id'])->update(['order_status' => 4]);
        if(empty($res)){
            return ['code' => -1,'msg' => '订单状态修改失败'];
        }
        //修改用户信息
        if(!empty($type)){
            $user_info = Db::name('shop_user')->where('user_id',$user_info['user_id'])->find();
        }
        $data = [
            'oneself_volume'  => $user_info['oneself_volume'] + $order_info['number'],
            'volume'          => $user_info['volume'] +  $order_info['number'],
        ];
        $res = Db::name('shop_user')->where('user_id',$user_info['user_id'])->update($data);
        if(empty($res)){
            return ['code' => -1,'msg' => '订单状态修改失败'];
        }
        //查看是否升级
        $this->userLevel($user_info['user_id']);
         //奖金推送
        $bonus = $this->bonusPush($user_info,$order_info);
        if($bonus){
            return ['code' => 10000,'msg' => '完成'];
        }else{
            return ['code' => -1,'msg' => '订单状态修改失败'];
        }

    }



}